package com.tree.backend.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tree.backend.common.Result;
import com.tree.backend.entity.Device;
import com.tree.backend.entity.OptimizationResult;
import com.tree.backend.entity.OptimizationTask;
import com.tree.backend.entity.SignalCollection;
import com.tree.backend.service.IDeviceService;
import com.tree.backend.service.IOptimizationResultService;
import com.tree.backend.service.IOptimizationTaskService;
import com.tree.backend.service.ISignalCollectionService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 结构分析控制器
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/structure")
public class StructureAnalysisController {

    private final IDeviceService deviceService;
    private final ISignalCollectionService signalCollectionService;
    private final IOptimizationTaskService optimizationTaskService;
    private final IOptimizationResultService optimizationResultService;

    /**
     * 获取结构分析概览数据
     */
    @GetMapping("/overview")
    public Result<Object> getStructureOverview() {
        // 设备总数
        long Devices = deviceService.count();
        
        // 信号采集总数
        long Signals = signalCollectionService.count();
        
        // 优化任务总数
        long Tasks = optimizationTaskService.count();
        
        // 优化成功率
        QueryWrapper<OptimizationResult> successWrapper = new QueryWrapper<>();
        successWrapper.eq("result_status", true);
        long successCount = optimizationResultService.count(successWrapper);
        long totalResults = optimizationResultService.count();
        double Rate = totalResults > 0 ? (double) successCount / totalResults * 100 : 0;
        
        return Result.success(new Object() {
            public final long totalDevices = Devices;
            public final long totalSignals = Signals;
            public final long totalTasks = Tasks;
            public final double successRate = Math.round(Rate * 100.0) / 100.0;
        });
    }

    /**
     * 获取设备类型分布统计
     */
    @GetMapping("/device-type-distribution")
    public Result<List<Map<String, Object>>> getDeviceTypeDistribution() {
        List<Device> devices = deviceService.list();
        Map<String, Long> typeCountMap = new HashMap<>();
        
        for (Device device : devices) {
            String deviceType = device.getDeviceType();
            typeCountMap.put(deviceType, typeCountMap.getOrDefault(deviceType, 0L) + 1);
        }
        
        List<Map<String, Object>> result = new ArrayList<>();
        long total = devices.size();
        
        for (Map.Entry<String, Long> entry : typeCountMap.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("type", entry.getKey());
            item.put("count", entry.getValue());
            item.put("percentage", total > 0 ? 
                Math.round((double) entry.getValue() / total * 10000) / 100.0 : 0);
            result.add(item);
        }
        
        return Result.success(result);
    }

    /**
     * 获取设备状态统计
     */
    @GetMapping("/device-status-stats")
    public Result<Object> getDeviceStatusStats() {
        QueryWrapper<Device> normalWrapper = new QueryWrapper<>();
        normalWrapper.eq("status", true);
        long normalCount = deviceService.count(normalWrapper);
        
        QueryWrapper<Device> faultWrapper = new QueryWrapper<>();
        faultWrapper.eq("status", false);
        long faultCount = deviceService.count(faultWrapper);
        
        long totalCount = deviceService.count();
        
        return Result.success(new Object() {
            public final long total = totalCount;
            public final long normal = normalCount;
            public final long fault = faultCount;
        });
    }

    /**
     * 获取信号质量分析
     */
    @GetMapping("/signal-quality-analysis")
    public Result<Object> getSignalQualityAnalysis(
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime) {
        
        QueryWrapper<SignalCollection> wrapper = new QueryWrapper<>();
        
        if (startTime != null && !startTime.isEmpty()) {
            wrapper.ge("collect_time", startTime);
        }
        if (endTime != null && !endTime.isEmpty()) {
            wrapper.le("collect_time", endTime);
        }
        
        List<SignalCollection> signals = signalCollectionService.list(wrapper);
        
        if (signals.isEmpty()) {
            return Result.success(new Object() {
                public final BigDecimal averageStrength = BigDecimal.ZERO;
                public final BigDecimal averageLatency = BigDecimal.ZERO;
                public final BigDecimal averagePacketLoss = BigDecimal.ZERO;
            });
        }
        
        BigDecimal totalStrength = BigDecimal.ZERO;
        BigDecimal totalLatency = BigDecimal.ZERO;
        BigDecimal totalPacketLoss = BigDecimal.ZERO;
        
        for (SignalCollection signal : signals) {
            if (signal.getSignalStrength() != null) {
                totalStrength = totalStrength.add(signal.getSignalStrength());
            }
            if (signal.getLatency() != null) {
                totalLatency = totalLatency.add(BigDecimal.valueOf(signal.getLatency()));
            }
            if (signal.getPacketLoss() != null) {
                totalPacketLoss = totalPacketLoss.add(signal.getPacketLoss());
            }
        }
        
        int count = signals.size();
        BigDecimal Strength = totalStrength.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP);
        BigDecimal Latency = totalLatency.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP);
        BigDecimal PacketLoss = totalPacketLoss.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP);
        
        return Result.success(new Object() {
            public final BigDecimal averageStrength = Strength;
            public final BigDecimal averageLatency = Latency;
            public final BigDecimal averagePacketLoss = PacketLoss;
        });
    }

    /**
     * 获取任务执行统计
     */
    @GetMapping("/task-execution-stats")
    public Result<Object> getTaskExecutionStats() {
        QueryWrapper<OptimizationTask> pendingWrapper = new QueryWrapper<>();
        pendingWrapper.eq("status", 0);
        long pendingCount = optimizationTaskService.count(pendingWrapper);
        
        QueryWrapper<OptimizationTask> runningWrapper = new QueryWrapper<>();
        runningWrapper.eq("status", 1);
        long runningCount = optimizationTaskService.count(runningWrapper);
        
        QueryWrapper<OptimizationTask> completedWrapper = new QueryWrapper<>();
        completedWrapper.eq("status", 2);
        long completedCount = optimizationTaskService.count(completedWrapper);
        
        QueryWrapper<OptimizationTask> failedWrapper = new QueryWrapper<>();
        failedWrapper.eq("status", 3);
        long failedCount = optimizationTaskService.count(failedWrapper);
        
        long totalCount = optimizationTaskService.count();
        
        return Result.success(new Object() {
            public final long total = totalCount;
            public final long pending = pendingCount;
            public final long running = runningCount;
            public final long completed = completedCount;
            public final long failed = failedCount;
        });
    }

    /**
     * 获取优化效果分析
     */
    @GetMapping("/optimization-effect-analysis")
    public Result<Object> getOptimizationEffectAnalysis(
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime) {
        
        QueryWrapper<OptimizationResult> wrapper = new QueryWrapper<>();
        
        if (startTime != null && !startTime.isEmpty()) {
            wrapper.ge("create_time", startTime);
        }
        if (endTime != null && !endTime.isEmpty()) {
            wrapper.le("create_time", endTime);
        }
        
        List<OptimizationResult> results = optimizationResultService.list(wrapper);
        
        if (results.isEmpty()) {
            return Result.success(new Object() {
                public final BigDecimal averageImprovement = BigDecimal.ZERO;
                public final long successCount = 0;
                public final long failedCount = 0;
            });
        }
        
        BigDecimal totalImprovement = BigDecimal.ZERO;
        long success = 0;
        long failed = 0;

        for (OptimizationResult result : results) {
            if (result.getImprovementRate() != null) {
                totalImprovement = totalImprovement.add(result.getImprovementRate());
            }
            if (Boolean.TRUE.equals(result.getResultStatus())) {
                success++;
            } else {
                failed++;
            }
        }
        
        BigDecimal average= totalImprovement.divide(
            BigDecimal.valueOf(results.size()), 2, RoundingMode.HALF_UP);

        long finalSuccess = success;
        long finalFailed = failed;
        return Result.success(new Object() {
            public final BigDecimal averageImprovement = average;
            public final long successCount = finalSuccess;
            public final long failedCount = finalFailed;
        });
    }

    /**
     * 获取任务类型分布
     */
    @GetMapping("/task-type-distribution")
    public Result<List<Map<String, Object>>> getTaskTypeDistribution() {
        List<OptimizationTask> tasks = optimizationTaskService.list();
        Map<String, Long> typeCountMap = new HashMap<>();
        
        for (OptimizationTask task : tasks) {
            String taskType = task.getTaskType();
            typeCountMap.put(taskType, typeCountMap.getOrDefault(taskType, 0L) + 1);
        }
        
        List<Map<String, Object>> result = new ArrayList<>();
        long total = tasks.size();
        
        for (Map.Entry<String, Long> entry : typeCountMap.entrySet()) {
            Map<String, Object> item = new HashMap<>();
            item.put("type", entry.getKey());
            item.put("count", entry.getValue());
            item.put("percentage", total > 0 ? 
                Math.round((double) entry.getValue() / total * 10000) / 100.0 : 0);
            result.add(item);
        }
        
        return Result.success(result);
    }

    /**
     * 获取优化成功率统计
     */
    @GetMapping("/optimization-success-rate")
    public Result<Object> getOptimizationSuccessRate() {
        QueryWrapper<OptimizationResult> successWrapper = new QueryWrapper<>();
        successWrapper.eq("result_status", true);
        long successCount = optimizationResultService.count(successWrapper);
        
        QueryWrapper<OptimizationResult> failedWrapper = new QueryWrapper<>();
        failedWrapper.eq("result_status", false);
        long failedCount = optimizationResultService.count(failedWrapper);
        
        long totalCount = optimizationResultService.count();
        double Rate = totalCount > 0 ? (double) successCount / totalCount * 100 : 0;
        
        return Result.success(new Object() {
            public final long total = totalCount;
            public final long success = successCount;
            public final long failed = failedCount;
            public final double successRate = Math.round(Rate * 100.0) / 100.0;
        });
    }

    /**
     * 获取网络拓扑结构
     */
    @GetMapping("/network-topology")
    public Result<Object> getNetworkTopology() {
        // 获取所有设备
        List<Device> devices = deviceService.list();
        
        // 构建网络拓扑结构
        List<Map<String, Object>> nodes = new ArrayList<>();
        List<Map<String, Object>> links = new ArrayList<>();
        
        // 添加设备节点
        for (Device device : devices) {
            Map<String, Object> node = new HashMap<>();
            node.put("id", device.getId());
            node.put("name", device.getDeviceName());
            node.put("type", device.getDeviceType());
            node.put("status", device.getStatus());
            node.put("location", device.getLocation());
            nodes.add(node);
        }
        
        // 基于设备类型和位置构建连接关系（简化版）
        // 在实际应用中，这里应该根据实际的网络连接关系来构建
        for (int i = 0; i < Math.min(nodes.size(), 5); i++) {
            for (int j = i + 1; j < Math.min(nodes.size(), 5); j++) {
                Map<String, Object> link = new HashMap<>();
                link.put("source", nodes.get(i).get("id"));
                link.put("target", nodes.get(j).get("id"));
                link.put("type", "connection");
                links.add(link);
            }
        }
        
        Map<String, Object> topology = new HashMap<>();
        topology.put("nodes", nodes);
        topology.put("links", links);
        topology.put("totalNodes", nodes.size());
        topology.put("totalConnections", links.size());
        
        return Result.success(topology);
    }
}